home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-1 / Inter.Net 55-1.iso / beos / PPBeDevKit.ZIP / PLAYERPR.TAR / PlayerPRO / Source / Import-Export / MADfg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-26  |  13.4 KB  |  528 lines

  1. /********************                        ***********************/
  2. //
  3. //    Player PRO 5.0 - DRIVER SOURCE CODE -
  4. //
  5. //    Library Version 5.0
  6. //
  7. //    To use with MAD Library for Mac: Symantec, CodeWarrior and MPW
  8. //
  9. //    Antoine ROSSET
  10. //    16 Tranchees
  11. //    1206 GENEVA
  12. //    SWITZERLAND
  13. //
  14. //    COPYRIGHT ANTOINE ROSSET 1996, 1997, 1998
  15. //
  16. //    Thank you for your interest in PlayerPRO !
  17. //
  18. //    FAX:                (+41 22) 346 11 97
  19. //    PHONE:             (+41 79) 203 74 62
  20. //    Internet:     RossetAntoine@bluewin.ch
  21. //
  22. /********************                        ***********************/
  23.  
  24. #include "MOD.h"
  25. #include "MAD.h"
  26. #include "MADFG.h"
  27. #include "RDriver.h"
  28.  
  29. #if defined(powerc) || defined(__powerc)
  30. enum {
  31.         PlayerPROPlug = kCStackBased
  32.         | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  33.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof( OSType)))
  34.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof( Ptr)))
  35.         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof( MADMusic*)))
  36.         | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof( PPInfoRec*)))
  37.         | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof( MADDriverSettings*)))
  38. };
  39.  
  40. ProcInfoType __procinfo = PlayerPROPlug;
  41. #else
  42. #include <A4Stuff.h>
  43. #endif
  44.  
  45. Ptr MADPlugNewPtr( long size, MADDriverSettings* init)
  46. {
  47.     if( init->sysMemory) return NewPtrSys( size);
  48.     else return NewPtr( size);
  49. }
  50.  
  51. Ptr MADPlugNewPtrClear( long size, MADDriverSettings* init)
  52. {
  53.     if( init->sysMemory) return NewPtrSysClear( size);
  54.     else return NewPtrClear( size);
  55. }
  56.  
  57. struct MusicPattern* oldDecompressPartitionMAD1( struct MusicPattern* myPat, short Tracks, MADDriverSettings *init)
  58. {
  59.     struct MusicPattern*    finalPtr;
  60.     Byte                     *srcPtr;
  61.     struct Command            *myCmd;
  62.     short                    maxCmd;
  63.     
  64.     finalPtr = ( struct MusicPattern*) MADPlugNewPtr( sizeof( struct oldPatHeader) + myPat->header.PatternSize * Tracks * sizeof( struct Command), init);
  65.     if( finalPtr == 0L) DebugStr("\pDecompressPartitionMAD1");
  66.     
  67.     BlockMove( myPat, finalPtr, sizeof( struct oldPatHeader));
  68.  
  69.     srcPtr = (Byte*) myPat->Commands;
  70.     myCmd = (struct Command*) finalPtr->Commands;
  71.     maxCmd = finalPtr->header.PatternSize * Tracks;
  72.     
  73.     /*** Decompression Routine ***/
  74.  
  75.     /*
  76.     First Byte = 0x03 -> Instrument + AmigaPeriod + Effect + Cmd
  77.     First Byte = 0x02 -> Instrument + AmigaPeriod
  78.     First Byte = 0x01 -> Effect + Cmd
  79.     First Byte = 0x00 -> nothing
  80.     */
  81.     
  82.     while( maxCmd != 0)
  83.     {
  84.         maxCmd--;
  85.         
  86.         switch( *srcPtr)
  87.         {
  88.             case 0x03:
  89.                 srcPtr++;
  90.                 
  91.                 ((short*)myCmd)[ 0] = *((short*) srcPtr);
  92.                 ((short*)myCmd)[ 1] = ((short*) srcPtr)[ 1];
  93.                 
  94.                 srcPtr += 4;
  95.             break;
  96.             
  97.             case 0x02:
  98.                 srcPtr++;
  99.                                 
  100.                 ((short*)myCmd)[ 0] = *((short*) srcPtr);
  101.                 ((short*)myCmd)[ 1] = 0L;
  102.                 
  103.                 srcPtr += 2;
  104.             break;
  105.             
  106.             case 0x01:
  107.                 srcPtr++;
  108.                 
  109.                 ((short*)myCmd)[ 0] = 0L;
  110.                 ((short*)myCmd)[ 1] = *((short*) srcPtr);
  111.                 
  112.                 srcPtr += 2;
  113.             break;
  114.             
  115.             case 0x00:
  116.                 srcPtr ++;
  117.                 
  118.                 *((long*)myCmd) = 0L;
  119.             break;
  120.             
  121.             default:
  122.                 DebugStr("\pDecompress MAD1 failed.");
  123.             break;
  124.         }
  125.         myCmd++;
  126.     }
  127.     
  128.     return finalPtr;
  129. }
  130.  
  131. struct Command* GetOldCommand( short PosX, short    TrackIdX, struct MusicPattern*    tempMusicPat)
  132. {
  133.     if( PosX < 0) PosX = 0;
  134.     else if( PosX >= tempMusicPat->header.PatternSize) PosX = tempMusicPat->header.PatternSize -1;
  135.         
  136.     return( & (tempMusicPat->Commands[ (tempMusicPat->header.PatternSize * TrackIdX) + PosX]));
  137. }
  138.  
  139. Cmd* GetMADCommand( register short PosX, register short    TrackIdX, register PatData*    tempMusicPat)
  140. {
  141.     if( PosX < 0) PosX = 0;
  142.     else if( PosX >= tempMusicPat->header.size) PosX = tempMusicPat->header.size -1;
  143.         
  144.     return( & (tempMusicPat->Cmds[ (tempMusicPat->header.size * TrackIdX) + PosX]));
  145. }
  146.  
  147. void pStrcpy(register unsigned char *s1, register unsigned char *s2)
  148. {
  149.     register short len, i;
  150.     
  151.     len = *s2;
  152.     for ( i = 0; i <= len; i++) s1[ i] = s2[ i];
  153. }
  154.  
  155. void mystrcpy( Ptr a, Ptr b)
  156. {
  157.     BlockMove( b + 1, a, b[ 0]);
  158. }
  159.  
  160. OSErr MADFG2Mad( Ptr MADPtr, long size, MADMusic *theMAD, MADDriverSettings *init)
  161. {
  162. short                     i, x;
  163. long                     inOutCount, OffSetToSample = 0L, z;
  164. OSErr                    theErr = noErr;
  165. Boolean                    MADConvert = false;
  166. Ptr                        tempPtr;
  167. long             finetune[16] = 
  168.                 {
  169.                     8363,    8413,    8463,    8529,    8581,    8651,    8723,    8757,
  170.                     7895,    7941,    7985,    8046,    8107,    8169,    8232,    8280
  171.                 };
  172.  
  173.  
  174. /**** Old MADFG variables ****/
  175.  
  176. oldMADSpec                *oldMAD;
  177.  
  178. oldMAD = (oldMADSpec*) MADPtr;
  179.  
  180.  
  181. /**** HEADER ****/
  182. if( oldMAD->MADIdentification == 'MADF') MADConvert = true;
  183. else if( oldMAD->MADIdentification == 'MADG') MADConvert = false;
  184. else return MADFileNotSupportedByThisPlug;
  185. OffSetToSample += sizeof( oldMADSpec);
  186.  
  187. // Conversion
  188. inOutCount = sizeof( MADSpec);
  189. theMAD->header = (MADSpec*) MADPlugNewPtrClear( inOutCount, init);    
  190. if( theMAD->header == 0L) return MADNeedMemory;
  191.  
  192. theMAD->header->MAD = 'MADI';
  193.  
  194. BlockMove( oldMAD->NameSignature, theMAD->header->name, 32);
  195. theMAD->header->numPat            = oldMAD->PatMax;
  196. theMAD->header->numChn            = oldMAD->Tracks;
  197. theMAD->header->numPointers        = oldMAD->numPointers;
  198. BlockMove( oldMAD->oPointers, theMAD->header->oPointers, 128);
  199. theMAD->header->speed            = 6;
  200. theMAD->header->tempo            = 125;
  201.  
  202. mystrcpy( theMAD->header->infos, (Ptr) "\pConverted by PlayerPRO MAD-F-G Plug (⌐Antoine ROSSET <rossetantoine@bluewin.ch>)");
  203.  
  204. /**** Patterns *******/
  205.  
  206. for( i = 0; i < oldMAD->PatMax; i++)
  207. {
  208.     struct MusicPattern        *tempPat, *tempPat2;
  209.     struct oldPatHeader        tempPatHeader;
  210.     
  211.     /** Lecture du header de la partition **/
  212.     if( !MADConvert)
  213.     {
  214.         inOutCount = sizeof( struct oldPatHeader);
  215.         
  216.         BlockMove( MADPtr + OffSetToSample, &tempPatHeader, inOutCount);
  217.     }
  218.     else tempPatHeader.PatternSize = 64L;
  219.     
  220.     /*************************************************/
  221.     /** Lecture du header + contenu de la partition **/
  222.     /*************************************************/
  223.     
  224.     if( tempPatHeader.CompressionMode == 'MAD1')
  225.     {
  226.         inOutCount = sizeof( struct MusicPattern) + tempPatHeader.PatBytes;
  227.     }
  228.     else
  229.     {
  230.         inOutCount = sizeof( struct MusicPattern) + oldMAD->Tracks * tempPatHeader.PatternSize * sizeof( struct Command);
  231.     }
  232.     
  233.     tempPat = (struct MusicPattern*) MADPlugNewPtr( inOutCount, init);
  234.     if( tempPat == 0L) DebugStr("\pMemory Prob1");
  235.     
  236.     if( MADConvert)
  237.     {
  238.         tempPat = (struct MusicPattern*) ((Ptr) tempPat + sizeof( struct oldPatHeader));
  239.         inOutCount -= sizeof( struct oldPatHeader);
  240.     }
  241.     
  242.     BlockMove( MADPtr + OffSetToSample, tempPat, inOutCount);
  243.     OffSetToSample += inOutCount;
  244.     
  245.     if( MADConvert)
  246.     {
  247.         tempPat = (struct MusicPattern*) ((Ptr) tempPat - sizeof( struct oldPatHeader));
  248.         tempPat->header.PatternSize = 64L;
  249.         tempPat->header.CompressionMode = 'NONE';
  250.         
  251.         for( x = 0; x < 20; x++) tempPat->header.PatternName[ x] = 0;
  252.         
  253.         tempPat->header.unused2 = 0L;
  254.     }
  255.     
  256.     if( tempPat->header.CompressionMode == 'MAD1')
  257.     {
  258.         tempPat2 = oldDecompressPartitionMAD1( tempPat, oldMAD->Tracks, init);
  259.         
  260.         DisposePtr( (Ptr) tempPat);
  261.         
  262.         tempPat = tempPat2;
  263.     }
  264.     
  265.     /**************/
  266.     /* CONVERSION */
  267.     /**************/
  268.     
  269.     theMAD->partition[ i] = (PatData*) MADPlugNewPtrClear( sizeof( PatHeader) + theMAD->header->numChn * tempPat->header.PatternSize * sizeof( Cmd), init);
  270.     if( theMAD->partition[ i] == 0L) return MADNeedMemory;
  271.     
  272.     theMAD->partition[ i]->header.size         = tempPat->header.PatternSize;
  273.     theMAD->partition[ i]->header.compMode     = 'NONE';
  274.     
  275.     BlockMove( tempPat->header.PatternName, theMAD->partition[ i]->header.name, 20);
  276.     
  277.     theMAD->partition[ i]->header.patBytes = 0L;        theMAD->partition[ i]->header.unused2 = 0L;
  278.     
  279.     for( x = 0; x < theMAD->partition[ i]->header.size; x++)
  280.     {
  281.         for( z = 0; z < theMAD->header->numChn; z++)
  282.         {
  283.             struct Command *oldCmd;
  284.             Cmd    *aCmd;
  285.             
  286.             aCmd = GetMADCommand(  x,  z, theMAD->partition[ i]);
  287.             
  288.             oldCmd     = GetOldCommand(    x,
  289.                                         z,
  290.                                         tempPat);
  291.             
  292.             aCmd->ins     = oldCmd->InstrumentNo;
  293.             if( oldCmd->AmigaPeriod == 0L) aCmd->note = 0xFF;
  294.             else aCmd->note     = oldCmd->AmigaPeriod + 22;
  295.             aCmd->cmd     = oldCmd->EffectCmd;
  296.             aCmd->arg     = oldCmd->EffectArg;
  297.             aCmd->vol    = 0xFF;
  298.             
  299.             if( aCmd->cmd == 0x0C)
  300.             {
  301.                 aCmd->vol    = 0x10 + (aCmd->arg & 0x00FF);
  302.                 aCmd->cmd     = 0;
  303.                 aCmd->arg     = 0;
  304.             }
  305.         }
  306.     }
  307. }
  308. for( i = theMAD->header->numPat; i < MAXPATTERN ; i++) theMAD->partition[ i] = 0L;
  309.  
  310. for( i = 0; i < MAXTRACK; i++)
  311. {
  312.     if( i % 2 == 0) theMAD->header->chanPan[ i] = MAX_PANNING/4;
  313.     else theMAD->header->chanPan[ i] = MAX_PANNING - MAX_PANNING/4;
  314.     
  315.     theMAD->header->chanVol[ i] = MAX_VOLUME;
  316. }
  317.  
  318.     theMAD->header->generalVol        = 64;
  319.     theMAD->header->generalSpeed    = 80;
  320.     theMAD->header->generalPitch    = 80;
  321.  
  322. /**** Instruments header *****/
  323.  
  324. theMAD->fid = ( InstrData*) MADPlugNewPtrClear( sizeof( InstrData) * (long) MAXINSTRU, init);
  325. if( !theMAD->fid) return MADNeedMemory;
  326.  
  327. theMAD->sample = ( sData**) MADPlugNewPtrClear( sizeof( sData*) * (long) MAXINSTRU * (long) MAXSAMPLE, init);
  328. if( !theMAD->sample) return MADNeedMemory;
  329.  
  330. for( i = 0; i < MAXINSTRU; i++) theMAD->fid[ i].firstSample = i * MAXSAMPLE;
  331.  
  332. for( i = 0; i < 64; i++)
  333. {
  334.     InstrData    *curIns = &theMAD->fid[ i];
  335.     
  336.     BlockMove( oldMAD->fid[ i].Filename, curIns->name, 32);
  337.     curIns->type = 0;
  338.     
  339.     if( oldMAD->fid[ i].insSize > 0)
  340.     {
  341.         sData    *curData;
  342.         
  343.         curIns->numSamples = 1;
  344.         curIns->volFade = DEFAULT_VOLFADE;
  345.         
  346.         curData = theMAD->sample[ i*MAXSAMPLE + 0] = (sData*) MADPlugNewPtrClear( sizeof( sData), init);
  347.         
  348.         curData->size        = oldMAD->fid[ i].insSize;
  349.         curData->loopBeg     = oldMAD->fid[ i].loopStart;
  350.         curData->loopSize     = oldMAD->fid[ i].loopLenght;
  351.         curData->vol        = oldMAD->fid[ i].volume;
  352.         curData->c2spd        = finetune[ oldMAD->fid[ i].fineTune];
  353.         curData->loopType    = 0;
  354.         curData->amp        = oldMAD->fid[ i].amplitude;
  355.         
  356.         curData->relNote    = 0;
  357.         
  358.         curData->data         = MADPlugNewPtr( curData->size, init);
  359.         if( curData->data == 0L) return MADNeedMemory;
  360.         
  361.         BlockMove( MADPtr + OffSetToSample, curData->data, curData->size);
  362.         OffSetToSample += curData->size;
  363.     }
  364.     else curIns->numSamples = 0;
  365. }
  366.  
  367. return noErr;
  368. }
  369.  
  370. OSErr TestoldMADFile( Ptr AlienFile)
  371. {
  372. OSType    *myMADSign = (OSType*) AlienFile;
  373.  
  374. if(    *myMADSign == 'MADF' || *myMADSign == 'MADG') return   noErr;
  375. else return  MADFileNotSupportedByThisPlug;
  376. }
  377.  
  378. OSErr ExtractoldMADInfo( PPInfoRec *info, Ptr AlienFile)
  379. {
  380.     oldMADSpec    *myMOD = ( oldMADSpec*) AlienFile;
  381.     long        PatternSize;
  382.     short        i;
  383.     short        tracksNo;
  384.     
  385.     /*** Signature ***/
  386.     
  387.     info->signature = myMOD->MADIdentification;
  388.     
  389.     /*** Internal name ***/
  390.     
  391.     myMOD->NameSignature[ 31] = '\0';
  392.     MADstrcpy( info->internalFileName, myMOD->NameSignature);
  393.  
  394.     /*** Tracks ***/
  395.     
  396.     info->totalTracks = myMOD->Tracks;
  397.         
  398.     /*** Total Patterns ***/
  399.     
  400.     info->totalPatterns = 0;
  401.     for( i = 0; i < 128; i++)
  402.     {
  403.         if( myMOD->oPointers[ i] >= info->totalPatterns)    info->totalPatterns = myMOD->oPointers[ i];
  404.     }
  405.     info->totalPatterns++;
  406.     
  407.     /*** Partition Length ***/
  408.     
  409.     info->partitionLength = myMOD->numPointers;
  410.     
  411.     /*** Total Instruments ***/
  412.     
  413.     for( i = 0, info->totalInstruments = 0; i < MAXINSTRU ; i++)
  414.     {
  415.         if( myMOD->fid[ i].insSize > 5) info->totalInstruments++;
  416.     }
  417.     
  418.     MADstrcpy( info->formatDescription, "MAD-FG Plug");
  419.  
  420.     return noErr;
  421. }
  422.  
  423. /*****************/
  424. /* MAIN FUNCTION */
  425. /*****************/
  426.  
  427. OSErr main( OSType order, char *AlienFileName, MADMusic *MadFile, PPInfoRec *info, MADDriverSettings *init)
  428. {
  429.     OSErr    myErr;
  430.     Ptr        AlienFile;
  431.     short    vRefNum, iFileRefI;
  432.     long    dirID, sndSize;
  433.     
  434. #ifndef powerc
  435.     long    oldA4 = SetCurrentA4();             //this call is necessary for strings in 68k code resources
  436. #endif
  437.  
  438.     c2pstr( AlienFileName);
  439.     
  440.     myErr = noErr;
  441.  
  442.     switch( order)
  443.     {
  444.         case 'IMPL':
  445.             myErr = FSOpen( (unsigned char*) AlienFileName, 0, &iFileRefI);
  446.             if( myErr == noErr)
  447.             {
  448.                 GetEOF( iFileRefI, &sndSize);
  449.             
  450.                 // ** MEMORY Test Start
  451.                 AlienFile = MADPlugNewPtr( sndSize * 2L, init);
  452.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  453.                 // ** MEMORY Test End
  454.                 
  455.                 else
  456.                 {
  457.                     DisposePtr( AlienFile);
  458.                     
  459.                     AlienFile = MADPlugNewPtr( sndSize, init);
  460.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  461.                     if( myErr == noErr)
  462.                     {
  463.                         myErr = TestoldMADFile( AlienFile);
  464.                         if( myErr == noErr)
  465.                         {
  466.                             myErr = MADFG2Mad( AlienFile, GetPtrSize( AlienFile), MadFile, init);
  467.                         }
  468.                     }
  469.                     DisposePtr( AlienFile);    AlienFile = 0L;
  470.                 }
  471.                 FSClose( iFileRefI);
  472.             }
  473.         break;
  474.         
  475.         case 'TEST':
  476.             myErr = FSOpen( (unsigned char*) AlienFileName, 0, &iFileRefI);
  477.             if( myErr == noErr)
  478.             {
  479.                 sndSize = 5000L;    // Read only 5000 first bytes for optimisation
  480.                 
  481.                 AlienFile = MADPlugNewPtr( sndSize, init);
  482.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  483.                 else
  484.                 {
  485.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  486.                     myErr = TestoldMADFile( AlienFile);
  487.                     
  488.                     DisposePtr( AlienFile);    AlienFile = 0L;
  489.                 }
  490.                 FSClose( iFileRefI);
  491.             }
  492.         break;
  493.  
  494.         case 'INFO':
  495.             myErr = FSOpen( (unsigned char*) AlienFileName, 0, &iFileRefI);
  496.             if( myErr == noErr)
  497.             {
  498.                 GetEOF( iFileRefI, &info->fileSize);
  499.             
  500.                 sndSize = 5000L;    // Read only 5000 first bytes for optimisation
  501.                 
  502.                 AlienFile = MADPlugNewPtr( sndSize, init);
  503.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  504.                 else
  505.                 {
  506.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  507.                     if( myErr == noErr)
  508.                     {
  509.                         myErr = ExtractoldMADInfo( info, AlienFile);
  510.                     }
  511.                     DisposePtr( AlienFile);    AlienFile = 0L;
  512.                 }
  513.                 FSClose( iFileRefI);
  514.             }
  515.         break;
  516.         
  517.         default:
  518.             myErr = MADOrderNotImplemented;
  519.         break;
  520.     }
  521.  
  522.     p2cstr( (unsigned char*) AlienFileName);
  523.  
  524.     #ifndef powerc
  525.         SetA4( oldA4);
  526.     #endif
  527.     return myErr;
  528. }